import { defineComponent, ref, toRefs, nextTick, watch, onMounted, toRaw, onBeforeUnmount } from 'vue';
import type { PropType } from 'vue';
import { storeToRefs } from 'pinia';
import { is } from 'bpmn-js/lib/util/ModelUtil';
import editor from '@wf/components/bpmnjs/store/editor';
import modelerStore from '@wf/components/bpmnjs/store/modeler';
import initViewer from './initViewer';
import { createNewDiagram } from '@wf/components/bpmnjs/utils';
import { setProcessStatus } from './drawViewer';
import './index.scss';
import { ElDrawer } from 'element-plus';
// import modulesAndModdle from '@wf/components/bpmnjs/components/Designer/modulesAndModdle';
import IndependViewer from '../IndependViewer/index.vue';

const Viewer = defineComponent({
  name: 'BpmnViewer',
  props: {
    xml: {
      type: String as PropType<string>,
      default: undefined
    },
    config: {
      type: Object,
      default: () => {}
    },
    processNodes: {
      type: Object,
      default: () => {}
    },
    subProcessXml: {
      type: String as PropType<string>,
      default: undefined
    }
  },
  setup(props, { emit }) {
    const editorStore = editor();
    const modeler = modelerStore();
    const { editorSettings } = storeToRefs(editorStore);
    const { xml, config, subProcessXml } = toRefs(props);
    const viewer = ref<HTMLDivElement | null>(null);
    const showNodeInfo = ref<Boolean>(false);
    const nodeInfo = ref<Record<string, any> | undefined>(undefined);
    const isSubProcess = ref<Boolean>(false);
    const subProcessNodes = ref<Record<string, any>>({});

    const findCurrentNode = (nodes: any, nodeId: string) => {
      let targetNode = undefined;
      for (const key in nodes) {
        if (targetNode) {
          console.log('当前找到的node', targetNode);
          return targetNode;
        }
        if (key == 'subProcessList') {
          for (const subKey in nodes[key]) {
            targetNode = findCurrentNode(nodes[key][subKey], nodeId);
          }
        } else {
          targetNode = nodes[key].find((node) => node.activityId == nodeId);
        }
      }
      return targetNode;
    };

    // 绘制动态流程图
    const drawDynamicViewer = () => {
      const bpmnModeler = modeler.getModeler;
      bpmnModeler.on('element.click', (e: any) => {
        console.log('e', e);

        const businessObject = e.element.businessObject;
        // 点击整体流程信息时不展示数据
        if (is(e.element, 'bpmn:Process')) {
          return;
        }
        if (is(e.element, 'bpmn:SubProcess')) {
          isSubProcess.value = true;
        } else {
          isSubProcess.value = false;
        }

        // 重置
        nodeInfo.value = undefined;

        // 寻找返回值中匹配的节点
        const nodeId = businessObject.get('id');
        const clickNode = findCurrentNode(props.processNodes, nodeId);
        if (clickNode) {
          nodeInfo.value = clickNode;
        }
        if (nodeInfo.value) {
          showNodeInfo.value = true;
        }
      });
    };

    const watchEditorSettings = watch(
      () => editorSettings.value,
      async () => {
        try {
          console.log('调用初始化Viewer');
          await nextTick();
          await initViewer(viewer);
          await createNewDiagram(toRaw(xml.value), editorSettings.value);
          drawDynamicViewer();
        } catch (e) {
          console.log(e);
        }
      },
      { deep: true, immediate: true }
    );

    const watchConfig = watch(
      // 由于config和xml同步修改，现在只监听config
      () => props.config,
      (value) => {
        editorStore.updateConfiguration(toRaw(value));
      },
      { deep: true }
    );

    const watchProcessNodes = watch(
      () => props.processNodes,
      (v) => {
        if (v && Object.keys(v).length) {
          const { finishedLineList, finishedNodeList, currentNodeList, subProcessList } = v;
          if (subProcessList) {
            subProcessNodes.value = subProcessList;
          }
          setProcessStatus(finishedLineList, finishedNodeList, currentNodeList);
        }
      },
      { deep: true, immediate: true }
    );

    onBeforeUnmount(() => {
      console.log('执行了销毁监听');
      watchEditorSettings();
      watchConfig();
      watchProcessNodes();
    });

    const renderUserTaskInfo = () => {
      return (
        <div>
          <div>节点名称: {nodeInfo.value.taskName}</div>
          {nodeInfo.value.starter && <div>发起人: {nodeInfo.value.starter.userName}</div>}
          {nodeInfo.value.approver && (
            <div>
              <div>审批人: {nodeInfo.value.approver.userName}</div>
              <div>审批结果: {nodeInfo.value.approveComment}</div>
            </div>
          )}
          <div>发起时间: {nodeInfo.value.processCreateTime}</div>
          <div>完成时间: {nodeInfo.value.taskCompleteTime}</div>
        </div>
      );
    };

    return () => (
      <div>
        <div ref={viewer} class="bpmn-viewer"></div>
        <ElDrawer v-model={showNodeInfo.value} title="节点信息" direction="rtl">
          {nodeInfo.value && renderUserTaskInfo()}
          {isSubProcess.value &&
            Object.keys(subProcessNodes.value).map((subKey) => {
              return (
                <div class="bpmn-subprocess">
                  <div>子实例Id: {subKey}</div>
                  <IndependViewer class="sub-viewer" v-model={[subProcessXml.value, 'xml']} processNodes={subProcessNodes.value[subKey]} />
                </div>
              );
            })}
        </ElDrawer>
      </div>
    );
  }
});

export default Viewer;
